using UnityEngine;
using UnityEditor; 
using System.Collections;
using System.Collections.Generic;


[CustomEditor(typeof(MoveByCurveOnUpdate))]  
public class MoveByCurveInspector : Editor
{
	public Character character;
	public CharacterAnimatedState state;

	MoveByCurveOnUpdate action;

	bool drawCurveForward;
	bool drawCurveUp;
	bool drawCurveRight;
 
	Vector3 offset;

	void FindReferences()
	{
		state = action.transform.parent.parent.GetComponent<CharacterAnimatedState>();
		character = state.transform.parent.parent.GetComponent<Character>();
	}

	public void OnDestory()
	{
		CustomAnimationSampler.SampleMovement(Vector3.zero);
	}

	private EditorWindow cachedCurveWindow;
	public override void OnInspectorGUI () 
	{  
		action = target as MoveByCurveOnUpdate;
	 
		offset = new Vector3(action.movementRight.Evaluate((float)CustomAnimationSampler.currentFrame),
		                     action.movementUp.Evaluate((float)CustomAnimationSampler.currentFrame),
		 					 action.movementForward.Evaluate((float)CustomAnimationSampler.currentFrame));
		CustomAnimationSampler.SampleMovement(offset);

		DrawDefaultInspector();

		if(character == null)
		{
			FindReferences();
		}

		if(GUILayout.Button("SaveAll"))
		{
			SaveAllCurves(action);
		}
		if(GUILayout.Button("LoadAll"))
		{
			LoadAllCurves(action);
		}

		drawCurveForward = EditorGUILayout.Foldout(drawCurveForward, "Forward Curve Key Value");
		if(drawCurveForward)
		{
			action.movementForward = EditorGUILayout.CurveField("Movement Forward", action.movementForward);
			DrawCurveKeyValue(action.movementForward);
			if(GUILayout.Button("Save"))
			{
				SaveOneCurve("movementForward",action.movementForward,action);
			}
			if(GUILayout.Button("Load"))
			{
				LoadOneCurve("movementForward",action.movementForward,action);
			}
		}

		drawCurveUp = EditorGUILayout.Foldout(drawCurveUp, "Up Curve Key Value");
		if(drawCurveUp)
		{
			action.movementUp = EditorGUILayout.CurveField("Movement Up", action.movementUp);
			DrawCurveKeyValue(action.movementUp);
			if(GUILayout.Button("Save"))
			{
				SaveOneCurve("movementForward",action.movementUp,action);
			}
			if(GUILayout.Button("Load"))
			{
				LoadOneCurve("movementForward",action.movementUp,action);
			}
		}

		drawCurveRight = EditorGUILayout.Foldout(drawCurveRight, "Right Curve Key Value");
		if(drawCurveRight)
		{
			action.movementRight = EditorGUILayout.CurveField("Movement Right", action.movementRight);
			DrawCurveKeyValue(action.movementRight);
			if(GUILayout.Button("Save"))
			{
				SaveOneCurve("movementForward",action.movementRight,action);
			}
			if(GUILayout.Button("Load"))
			{
				LoadOneCurve("movementForward",action.movementRight,action);
			}
		}

		if(EditorWindow.focusedWindow != null)
		{
			if(EditorWindow.focusedWindow.ToString().Contains("CurveEditor"))
			{
				if(cachedCurveWindow == null)
				{
					cachedCurveWindow = (EditorWindow)Object.Instantiate(EditorWindow.focusedWindow);
				}
			}
		}
		if(cachedCurveWindow != null)
		{
			cachedCurveWindow.Show();
			cachedCurveWindow.Focus();
		}

	}
	
	void DrawCurveKeyValue(AnimationCurve curve)
	{
		EditorGUILayout.BeginHorizontal();
		EditorGUILayout.LabelField("Frame", GUILayout.MaxWidth(100));
		EditorGUILayout.LabelField("Value", GUILayout.MaxWidth(100));
		EditorGUILayout.EndHorizontal();
		int toRemove = -1;
		Keyframe[] keys = curve.keys;
		for(int i = 0; i < keys.Length; i++)
		{
			Keyframe kf = keys[i];
			EditorGUILayout.BeginHorizontal();
			float time = EditorGUILayout.FloatField(kf.time, GUILayout.MaxWidth(100));
			float value = EditorGUILayout.FloatField(kf.value, GUILayout.MaxWidth(100));
			bool remove = GUILayout.Button("Rmv", GUILayout.MaxWidth(50));
			EditorGUILayout.EndHorizontal();

			if(remove)
			{
				toRemove = i;
			}
			else if(time != kf.time || value != kf.value) 
			{
				kf.time = time;
				kf.value = value;
				curve.MoveKey(i, kf);
			}
		}

		bool addKeyFrame = GUILayout.Button("Add Key Frame", GUILayout.MaxWidth(250));


		if(toRemove >= 0)
		{
			curve.RemoveKey(toRemove);
		}
		else if(addKeyFrame)
		{
			if(curve.keys.Length > 0 )
			{
				Keyframe last = curve.keys[curve.length - 1];
				curve.AddKey(new Keyframe(last.time + 1, last.value));
			}
			else
			{
				curve.AddKey(new Keyframe(0, 0));
			}
		}
	}

	public void SaveAllCurves(MoveByCurveOnUpdate curveAction)
	{
		SaveOneCurve("movementForward",curveAction.movementForward,curveAction);
		SaveOneCurve("movementRight",curveAction.movementRight,curveAction);
		SaveOneCurve("movementUp",curveAction.movementUp,curveAction);
	}

	public void SaveOneCurve(string curveName,AnimationCurve curve,CharacterAction action)
	{
		string characterName = "";
		characterName = character.gameObject.name;
		string stateName = state.gameObject.name;
		string path = "Assets/CharacterData/" + characterName + "/" + stateName + "/" + action.name + "/" ;
		Debug.LogError(path);
		AnimationClip clip = new AnimationClip();
		if(!System.IO.Directory.Exists(path))
		{
			Debug.LogError("aa");
			System.IO.Directory.CreateDirectory(path);
		}

		if(!System.IO.File.Exists(path + curveName + ".anim"))
		{
			AssetDatabase.CreateAsset (clip, path + curveName + ".anim");
		}
		else
		{
			Debug.LogError("bb");
			clip = (AnimationClip)AssetDatabase.LoadAssetAtPath(path + curveName + ".anim",typeof(AnimationClip));
			Debug.LogError("clip = "+ clip);
		}
		
		clip.SetCurve("", typeof(Transform), "localPosition.x", curve);
		
		AssetDatabase.SaveAssets();
	}

	public void LoadAllCurves(MoveByCurveOnUpdate curveAction)
	{
		LoadOneCurve("movementForward",curveAction.movementForward,curveAction);
		LoadOneCurve("movementRight",curveAction.movementRight,curveAction);
		LoadOneCurve("movementUp",curveAction.movementUp,curveAction);
	}

	public void LoadOneCurve(string curveName,AnimationCurve curve,MoveByCurveOnUpdate action)
	{
		string characterName = character.gameObject.name;
		string stateName = state.gameObject.name;
		string path = "Assets/CharacterData/" + characterName + "/" + stateName + "/" + action.name + "/";
		Debug.LogError(path);
		AnimationClip clip = (AnimationClip)AssetDatabase.LoadAssetAtPath(path + curveName + ".anim",typeof(AnimationClip));
		if(clip != null)
		{
			AnimationClipCurveData[] data = AnimationUtility.GetAllCurves(clip);
			if(curveName == "movementForward")
			{
				action.movementForward = data[0].curve;
			}
			if(curveName == "movementRight")
			{
				action.movementRight = data[0].curve;
			}
			if(curveName == "movementUp")
			{
				action.movementUp = data[0].curve;
			}

			Repaint();

		}
		else
		{
			EditorUtility.DisplayDialog("Error","no data saved, please save first","ok");
		}

	}
}


 